import axios from 'axios'
import _ from 'lodash'
const qs = require('qs')
import router from '@/router/index'
import { Notification, MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken,removeToken } from '@/utils/auth'
import { getRandomSecretKey } from '@/utils/index.js'
import errorCode from '@/utils/errorCode'
const cryptoJs = require('crypto')
import { inSubstrate } from '@/utils/parent_connect/receiveParentApi'
import { noticeResponseCode } from '@/utils/parent_connect/noticeParentApi'
import { encrypt,decrypt } from '@/utils/DES3';
// import { MD5 } from 'crypto-js'
import Vue from "vue";
import i18n from '@/language/index'
const vueObj = new Vue({ i18n });

// 使用节流避免一次性提示出太多错误
const errMsg = _.throttle(
  function (msg) {
    Notification.error({
      title: msg,
    });
    //Message({ showClose: true, message: msg, type: "error" });
  },
  1000,
  {
    trailing: false,
  }
);

// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项，表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时
  timeout: 20000,
});
// request拦截器
service.interceptors.request.use(
  (config) => {
    //config.headers[constant.tokenKey] = getToken()
    //这个配置是告诉后端这是一个ajax请求(不可修改)
    config.headers["X-Requested-With"] = "XMLHttpRequest";
    config.headers['Content-Type'] = 'application/json';
    // 是否需要设置 token
    //const isToken = (config.headers || {}).isToken === false
    //if (getToken() && !isToken) {
    //config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
    //config.headers[constant.tokenKey] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
    //}

    // get请求映射params参数
    if (config.isExport && config.isExport === true) {
      config.headers["exportType"] = "XLSX";
    }

    if (config.method === "get") {
      config.paramsSerializer = function (params) {
        return qs.stringify(params, { arrayFormat: "repeat" });
      };
    }

    if (config.method === "get" && config.params) {
      let url = config.url + "?";
      for (const propName of Object.keys(config.params)) {
        const value = config.params[propName];
        var part = encodeURIComponent(propName) + "=";
        if (value !== null && typeof value !== "undefined") {
          if (typeof value === "object") {
            for (const key of Object.keys(value)) {
              let params = propName + "[" + key + "]";
              var subPart = encodeURIComponent(params) + "=";
              url += subPart + encodeURIComponent(value[key]) + "&";
            }
          } else {
            url += part + encodeURIComponent(value) + "&";
          }
        }
      }

    url = url.slice(0, -1);
    config.params = {};
    config.url = url;
  }

  config.data = config.data ? JSON.stringify(config.data) : '';

  let cryptoConfig = window.localStorage.getItem('crypto') ? JSON.parse(window.localStorage.getItem('crypto')) : undefined;
  // 加密逻辑
  if(config.method != "get" && cryptoConfig && cryptoConfig.cryptoEnable === true && cryptoConfig.cryptoSaltName) {
    let cryptoSalt = getRandomSecretKey(8);
    let secretKey = getRandomSecretKey(24);
    let cryptoStr = config.data// ? JSON.stringify(config.data) : '';
    // 如果加在前面
    if(cryptoConfig.cryptoStrategy === 'BEFORE') {
      cryptoStr = secretKey + cryptoStr;
    } else {
      cryptoStr = cryptoStr + secretKey;
    }
    // 加密
    config.data = encrypt(secretKey,cryptoStr,cryptoSalt);
    config.headers[cryptoConfig.cryptoSaltName] = cryptoSalt;
    config.headers[cryptoConfig.cryptoSecretKeyName] = secretKey;
  }

  // 加签
  let signConfig = window.localStorage.getItem('sign') ? JSON.parse(window.localStorage.getItem('sign')) : undefined;
  if(signConfig && signConfig.signEnable === true && signConfig.signSaltName) {
    let signSalt = getRandomSecretKey();

    let signStr = config.data;
    // 如果加在前面
    if(signConfig.signStrategy === 'BEFORE') {
      signStr = signSalt + signStr;
    } else {
      signStr = signStr + signSalt;
    }
    let obj = cryptoJs.createHash('md5');
    obj.update((signSalt + signStr))
    let sign = obj.digest('hex');

    config.headers[signConfig.signSaltName] = signSalt;
    config.headers[signConfig.signName] = sign;
  }
  config.headers['Content-Type'] = 'application/json';

  return config
}, error => {
    console.log(error)
    Promise.reject(error)
})

// 响应拦截器
service.interceptors.response.use(
  (res) => {
    // 未设置状态码则默认成功状态
    const code = res.status || 200;

    // 获取错误信息
    const msg = res.data.message || ""; //errorCode[code] || res.data.message || errorCode['default']
    if (code === 401) {
      //发个消息给父容器
      noticeResponseCode(code);
      MessageBox.confirm('登录状态已过期，您需要重新登录', '系统提示',
        {
          confirmButtonText: '重新登录',
          type: 'warning',
          lockScroll: true,
          closeOnClickModal: false,
          closeOnPressEscape: false,
          closeOnHashChange: false,
          showCancelButton: false
        }
      ).then(() => {
        console.log('req 401 logout')
        store.dispatch('LogOut').then(() => {
          location.href = res.data.url//'/index';
        })
      })
    } else if (code === 500) {
      errMsg(`${msg}`);
      return Promise.reject(new Error(msg));
    } else if (code !== 200) {
      errMsg(`${msg}`);
      return Promise.reject("error");
    } else {

      if(res.request.responseType && res.request.responseType == 'blob') {
        return res;
      }
      if(res.data.retStatus == 'SUCCESS') {

        return res.data;
      } else if (res.data.retStatus == "FAIL") {
        let msgType = "error";
        // 如果不在主应用中才需要跳转去
        if (!inSubstrate()) {
          //失败的情况需要判断
          switch (res.data.code) {
            case "CPWD":
              //跳转修改密码页面
              router.push({ path: "/pwdChange" }).catch(() => {});
              msgType = "info";
              break;
            case "NPWD":
              //跳转设置新密码页面
              router.push({ path: "/pwdSet" }).catch(() => {});
              msgType = "info";
              break;
            case "DEPT":
              //选择机构
              router.push({ path: "/chooseDept" }).catch(() => {});
              msgType = "info";
              break;
          }
        }
        if (msgType == "error") {
          errMsg(`${res.data.message}`);
        }

        return Promise.reject("error");
      }
    }
  },
  (error) => {
    console.log("error,", error);

    let { message } = error;
    if(error.response.status === 403) {
      MessageBox.confirm('没有权限，请为用户分配角色权限', '系统提示',
        {
          confirmButtonText: '知道了',
          type: 'warning',
          lockScroll: true,
          closeOnClickModal: false,
          closeOnPressEscape: false,
          closeOnHashChange: false,
          showCancelButton: false
        }
      ).then(() => {
        // store.dispatch('LogOut').then(() => {
        //   location.href = '/index';
        // })
      })
      return;
    }
    //如果是未登录
    if(error.response.status == 401) {

      errMsg(`登录超时或未登录`)
      // router.push({path: '/login'}).catch(()=>{});
      store.dispatch('LogOut').then(() => {
        removeToken();
        location.href = error.response.data.url//'/index';
      })
      return;
    }

    if (message == "Network Error") {
      message = "后端连接异常";
    } else if (message.includes("timeout")) {
      message = "系统请求超时, 请检查网络连接";
    } else if (message.includes("Request failed with status code")) {
      message = "系统接口" + message.substr(message.length - 3) + "异常";
    }
    errMsg(`${message}`);
    // Message({
    //   message: message,
    //   type: 'error',
    //   duration: 5 * 1000
    // })
    return Promise.reject(error);
  }
);

export default service;
